package srconfig

import (
	"strconv"

	"gitee.com/zhongguo168a/gocodes/datax"
	"gitee.com/zhongguo168a/gocodes/datax/mapx"
	"gitee.com/zhongguo168a/gocodes/datax/schemax"
	"gitee.com/zhongguo168a/gocodes/datax/schemax/configx"
	"gitee.com/zhongguo168a/gocodes/datax/treex"
)

func init() {

}

type ConfigService struct {
}

func (p *ConfigService) LoadConfig() {
}

func (p *ConfigService) ToSaveFileMap(set *configx.ConfigRepo) datax.M {
	//justifyBySchema_link编号转化成名字(set)
	justifyToSave(set)
	return toMap(set)
}

func justifyBySchema_link编号转化成名字(set *configx.ConfigRepo) {
	set.IndexTree().Walk(func(node *treex.TreeNode) bool {
		if node.Data == nil {
			return true
		}
		c := node.Data.(*configx.ConfigTreeItem)
		decl := c.GetSchema()
		visitor := schemax.NewVisitor(decl, c.Get原始数据())
		visitor.SetTarget(c.Get原始数据())
		visitor.SetHandler(func(ctx *schemax.VisitorContext) {
			switch ctx.CurrentDecl.(type) {
			case *schemax.ClassDecl:
				link := ctx.CurrentField.Tags["link"]
				if link != "" {
					linkConfig := set.GetBy编号(link)
					ctx.SetFieldValue(linkConfig.M名称)
				}
			}
		})
		return true
	})
}

func toMap(set *configx.ConfigRepo) datax.M {
	result := datax.M{}
	set.IndexTree().Walk(func(node *treex.TreeNode) bool {
		if node.Data == nil {
			return true
		}
		c := node.Data.(*configx.ConfigTreeItem)
		m := datax.M{}
		result[node.Id] = m
		mapx.Copy(c.Get原始数据(), m)
		// todo: 优化继承关系在运行时?
		switch c.L类型 {
		case "模型_帧动画":
			fallthrough
		case "图标":
			fallthrough
		case "图集":
			fallthrough
		case "音乐":
			fallthrough
		case "音效":
			fallthrough
		case "纹理":
			m["_parent"] = c.F父编号
			m["_type"] = c.L类型
			m["_catalog"] = c.F分类
			m["_namespace"] = c.M命令空间
		default:
			m["_type"] = c.L类型
			m["_name"] = c.M名称
			m["_catalog"] = c.F分类
			m["_parent"] = c.F父编号
			m["_namespace"] = c.M命令空间
			m["_default"] = c.M默认
			m["_unique"] = c.W唯一的
		}

		return true
	})

	return result
}

// 简化配置
// 1. 清除掉空的,默认的数据
// 2. 数据继承模式
func simply(set *configx.ConfigRepo) {
	// todo: 优化
	set.IndexTree().Walk(func(node *treex.TreeNode) bool {
		if node.Data == nil {
			return true
		}
		配置 := node.Data.(*configx.ConfigTreeItem)
		配置.Set数据(mapx.FilterMapNotDefault(配置.Get数据()))
		// 继承
		if node.Parent != nil {
			dataParent := node.Parent.(*treex.TreeNode)
			if dataParent.Data != nil {
				父配置 := dataParent.Data.(*configx.ConfigTreeItem)
				数据 := mapx.FilterMap(配置.Get数据(), func(parent map[string]interface{}, key string, val interface{}) (x bool) {
					if 父配置.Get数据() == nil { // 父数据不存在, key存在
						return false
					}
					父数据 := 父配置.Get数据()[key]
					switch v := val.(type) {
					case map[string]interface{}:
						switch pv := 父数据.(type) {
						case map[string]interface{}:
							if v == nil && pv == nil {
								//相同过滤掉
								x = true
							} else {
								// 继续遍历
							}

						}
					default:
						x = 父数据 == v
					}

					return
				})

				配置.Set数据(数据)
			}
		}
		return true
	})
}

// 调整成用于保存的数据
func justifyToSave(set *configx.ConfigRepo) {
	set.IndexTree().Walk(func(node *treex.TreeNode) bool {
		if node.Data == nil {
			return true
		}
		配置 := node.Data.(*configx.ConfigTreeItem)
		数据 := 配置.Get数据()
		switch 配置.F分类 {
		case "角色":
			justifyToSave_角色(set, 配置, 数据)
		case "任务":
			justifyToSave_任务(set, 配置, 数据)
		case "统计":
			justifyToSave_统计(set, 配置, 数据)
		case "卡包":
			justifyToSave_卡包(set, 配置, 数据)
		case "商店":
			justifyToSave_商店(set, 配置, 数据)
		case "执行":
			justifyToSave_执行(set, 配置, 数据)
		case "卡本":
			justifyToSave_卡本(set, 配置, 数据)
		}
		return true
	})

}

func justifyToSave_角色(set *configx.ConfigRepo, 配置 *configx.ConfigTreeItem, 数据 map[string]interface{}) {
	{ // 卡包

	}
}
func justifyToSave_角色_卡包(set *configx.ConfigRepo, 配置 *configx.ConfigTreeItem, 数据 map[string]interface{}) {

}

func justifyToSave_卡包(set *configx.ConfigRepo, 配置 *configx.ConfigTreeItem, 数据 map[string]interface{}) {

}

func justifyToSave_卡本(set *configx.ConfigRepo, 配置 *configx.ConfigTreeItem, 数据 map[string]interface{}) {
	// 卡页组合
	卡页组合 := []string{}
	_ = set.DictBy分类("卡包").ForRange(func(key string, val *configx.ConfigTreeItem) error {
		if val.M默认 {
			return nil
		}
		卡包数据 := val.Get数据()
		组合到卡本 := mapx.String(卡包数据, "组合到卡本")
		if 组合到卡本 == 配置.B编号 {
			卡页组合 = append(卡页组合, key)
		}
		return nil
	})
	卡页组合字典 := datax.M{}
	for i := 0; i < len(卡页组合); i++ {
		卡页组合字典[strconv.Itoa(i)] = 卡页组合[i]
	}
	mapx.SetByPath(配置.Get原始数据(), "/卡页组合", 卡页组合字典)
	mapx.SetByPath(配置.Get数据(), "/卡页组合", 卡页组合字典)
}

func justifyToSave_商店(set *configx.ConfigRepo, 配置 *configx.ConfigTreeItem, 数据 map[string]interface{}) {
	商店编号 := 配置.B编号
	商品集 := mapx.MapByPath(数据, "/商品集", false)
	if 商品集 != nil {
		for _, ival := range 商品集 {
			商品编号 := ival.(string)
			配置项 := set.GetBy编号(商品编号)
			if 配置项 != nil {
				任务数据 := 配置项.Get数据()
				mapx.SetByPath(任务数据, "/商店", 商店编号)
			}
		}
	}
}

func justifyToSave_统计(set *configx.ConfigRepo, 配置 *configx.ConfigTreeItem, 数据 map[string]interface{}) {

}
func justifyToSave_执行(set *configx.ConfigRepo, 配置 *configx.ConfigTreeItem, 数据 map[string]interface{}) {

}

func justifyToSave_任务(set *configx.ConfigRepo, 配置 *configx.ConfigTreeItem, 数据 map[string]interface{}) {
	功能编号 := mapx.String(数据, "功能")
	功能主体 := mapx.Int(数据, "功能主体")
	{
		统计编号 := mapx.String(数据, "统计")
		if 统计编号 != "" {
			配置项 := set.GetBy编号(统计编号)
			if 配置项 != nil {
				配置数据 := 配置项.Get数据()
				mapx.SetByPath(配置数据, "/功能主体", 功能主体)
				mapx.SetByPath(配置数据, "/功能", 功能编号)
			}
		}
	}

	switch 配置.L类型 {
	case "任务_集合":
		任务集 := mapx.MapByPath(数据, "/任务集", false)
		if 任务集 != nil {
			for _, ival := range 任务集 {
				val := ival.(datax.M)
				任务编号 := mapx.String(val, "任务")
				配置项 := set.GetBy编号(任务编号)
				if 配置项 != nil {
					任务数据 := 配置项.Get数据()
					mapx.SetByPath(任务数据, "/父任务", 配置.B编号)
					mapx.SetByPath(任务数据, "/功能主体", 功能主体)
					mapx.SetByPath(任务数据, "/功能", 功能编号)
					justifyToSave_任务(set, 配置项, 任务数据)
				}
			}
		}
	}

}
